package com.lytoyo.neihanduanzi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lytoyo.neihanduanzi.mapper.StatusMapper;
import com.lytoyo.neihanduanzi.mapper.UserAttentionMapper;
import com.lytoyo.neihanduanzi.model.Result;
import com.lytoyo.neihanduanzi.model.dto.StatusDto;
import com.lytoyo.neihanduanzi.model.user.UserAttention;
import com.lytoyo.neihanduanzi.service.UserAttentionService;
import com.lytoyo.neihanduanzi.utils.AuthContextHolder;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Package:com.lytoyo.neihanduanzi.service.impl
 *
 * @ClassName:UserAttentionServiceImpl
 * @Create:2025/4/29 10:24
 **/
@Service
@Slf4j
public class UserAttentionServiceImpl extends ServiceImpl<UserAttentionMapper, UserAttention> implements UserAttentionService {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private StatusMapper statusMapper;


    /**
     * 关注用户
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result attention(Long userId,Long fan) {
        UserAttention one = this.getOne(new LambdaQueryWrapper<UserAttention>().eq(UserAttention::getUserId, userId));
        if(null != one) return Result.success(null);

        //关注表添加关注信息
        CompletableFuture<Void> saveAttention = CompletableFuture.runAsync(() -> {
            UserAttention userAttention = new UserAttention();
            userAttention.setUserId(userId)
                    .setFan(fan);
            this.save(userAttention);
        }, threadPoolExecutor);
        //当前用户关注量+1
        CompletableFuture<Void> fanAttentionAdd = CompletableFuture.runAsync(() -> {
            statusMapper.update(new LambdaUpdateWrapper<StatusDto>()
                    .eq(StatusDto::getUserId, fan)
                    .eq(StatusDto::getType, "0702")
                    .setSql("amount = amount + 1"));
        },threadPoolExecutor);
        //被关注者粉丝量加1
        CompletableFuture<Void> fanAdd = CompletableFuture.runAsync(() -> {
            statusMapper.update(new LambdaUpdateWrapper<StatusDto>()
                    .eq(StatusDto::getUserId, userId)
                    .eq(StatusDto::getType, "0701")
                    .setSql("amount = amount + 1"));
        },threadPoolExecutor);
        CompletableFuture.allOf(saveAttention,fanAttentionAdd,fanAdd);
        return Result.success(null);
    }

    /**
     * 取消关注
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result subAttention(Long userId,Long fan) {
        UserAttention one = this.getOne(new LambdaQueryWrapper<UserAttention>().eq(UserAttention::getUserId, userId));
        if(null == one) return Result.success(null);
        //关注表删除关注信息
        CompletableFuture<Void> subAttention = CompletableFuture.runAsync(() -> {
            this.remove(new LambdaQueryWrapper<UserAttention>()
                            .eq(UserAttention::getUserId,userId)
                            .eq(UserAttention::getFan,fan));
        },threadPoolExecutor);

        //当前用户关注量减1
        CompletableFuture<Void> fanAttentionSub = CompletableFuture.runAsync(() -> {
            statusMapper.update(new LambdaUpdateWrapper<StatusDto>()
                    .eq(StatusDto::getUserId, fan)
                    .eq(StatusDto::getType, "0702")
                    .setSql("amount = amount - 1"));
        },threadPoolExecutor);

        //被关注者粉丝量减1
        CompletableFuture<Void> fanSub = CompletableFuture.runAsync(() -> {
            statusMapper.update(new LambdaUpdateWrapper<StatusDto>().eq(StatusDto::getUserId, userId)
                    .eq(StatusDto::getType, "0701")
                    .setSql("amount = amount - 1"));
        },threadPoolExecutor);
        CompletableFuture.allOf(subAttention,fanAttentionSub,fanSub);
        return Result.success(null);
    }
}
